/*
 * Created on 2006-9-25
 *
 */
package edu.pku.sei.modeler.locator;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.draw2d.ColorConstants;
import org.eclipse.draw2d.Figure;
import org.eclipse.draw2d.LightweightSystem;
import org.eclipse.draw2d.XYLayout;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CTabFolder;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

import edu.pku.sei.modeler.model.common.ModelRegistry;
import edu.pku.sei.modeler.model.core.MetaModel;
import edu.pku.sei.modeler.model.structure.AbsoluteLocatorAdapter;
import edu.pku.sei.modeler.model.structure.AbstractLocator;
import edu.pku.sei.modeler.model.structure.ActivationLocatorAdapter;
import edu.pku.sei.modeler.model.structure.CustomerLocatorAdapter;
import edu.pku.sei.modeler.model.structure.PortLocatorAdapter;
import edu.pku.sei.modeler.model.structure.StructureFactory;

/**
 * @author zhangle
 * @author xy
 */
public class DesignMainWin {
	private MetaModel model;
	private Shell shell;
	private int returnCode = SWT.CANCEL;
	private Figure contents;
	private Point origin;
	//private AbstractLocator currentLocator;
	private List locatorList = new ArrayList();
	private int locatorIndex = 0;
	private AbstractLocator inputLocator;
	//private int subpartNum = 1;
	//private Rectangle curBound;
	//private Figure demoFigure;
	//private List subFigures;
	
	public DesignMainWin(Shell parent, int style, AbstractLocator inputLocator) {
		shell = new Shell(parent, style);
		shell.setSize(700, 400);
		shell.setText("Locator Design Test");
		this.inputLocator = inputLocator;
	}
	public DesignMainWin(Shell parent, AbstractLocator inputLocator) {
		shell = new Shell(parent);
		shell.setSize(700, 400);
		shell.setText("Locator Design Test");
		this.inputLocator = inputLocator;
	}
	
	public DesignMainWin(Display display) {
		shell = new Shell(display);
		shell.setSize(700, 400);
		shell.setText("Locator Design Test");
	}
	
	public void setModel(MetaModel model) {
		this.model = model;
	}
	
	public int open() {
		createControl(shell);
		shell.open();
		contents.setBackgroundColor(ColorConstants.button);
		while (!shell.isDisposed())
			while (!shell.getDisplay().readAndDispatch())
				shell.getDisplay().sleep();
		return returnCode;
	}
	
	public static void main(String args[]) {
		Display d = new Display();
		DesignMainWin mainWin = new DesignMainWin(d);
		mainWin.open();
	}
	
	public void createControl(Shell shell) {
		LightweightSystem lws = new LightweightSystem(shell);
		
		contents = new Figure();
		XYLayout contentsLayout = new XYLayout();
		contents.setLayoutManager(contentsLayout);
		
		Figure mainFigure = new DemoFigure("Parent");
		Rectangle mainBound = new Rectangle(50, 50, 120, 140);
		contents.add(mainFigure);
		contents.setConstraint(mainFigure, mainBound);
		
		lws.setContents(contents);

		shell.setLayout(new FormLayout());
		FormData data = new FormData();
		data.top = new FormAttachment(0, 0);
		data.bottom = new FormAttachment(100, 0);
		data.left = new FormAttachment(0, 200);
		data.right = new FormAttachment(100, 0);
		Composite comp = new Composite(shell, SWT.NONE);
		comp.setLayoutData(data);
		
		data = new FormData();
		data.top = new FormAttachment(0, 220);
		data.bottom = new FormAttachment(100, 0);
		data.left = new FormAttachment(0, 0);
		data.right = new FormAttachment(0, 200);
		Composite comp2 = new Composite(shell, SWT.NONE);
		comp2.setLayoutData(data);
		
		createTabs(comp);
		createPreview(comp2);
	}
	
	protected void createTabs(Composite comp) {
		PortLocatorAdapter pl;
		ActivationLocatorAdapter al;
		AbsoluteLocatorAdapter absl;
		CustomerLocatorAdapter cl;
		
		StructureFactory sf = null;
		try {
			sf = (StructureFactory)ModelRegistry.getRegistry().getStructureFactory(model);
		}
		catch(Exception e) {
			e.printStackTrace();
		}
		if(sf == null)return;

		int index = 0;
		if(inputLocator instanceof PortLocatorAdapter) {
			pl = (PortLocatorAdapter)inputLocator;
			index = 0;
		} else {
			pl = sf.createPortLocatorAdapter();
		}
		
		if(inputLocator instanceof ActivationLocatorAdapter) {
			al = (ActivationLocatorAdapter)inputLocator;
			index = 1;
		} else {
			al = sf.createActivationLocatorAdapter();
		}
		
		if(inputLocator instanceof AbsoluteLocatorAdapter) {
			absl = (AbsoluteLocatorAdapter)inputLocator;
			index = 2;
		} else {
			absl = sf.createAbsoluteLocatorAdapter();
		}
		
		if(inputLocator instanceof CustomerLocatorAdapter) {
			cl = (CustomerLocatorAdapter)inputLocator;
			index = 3;
		} else {
			cl = sf.createCustomerLocatorAdapter();
		}
		
		locatorList.add(pl);
		locatorList.add(al);
		locatorList.add(absl);
		locatorList.add(cl);
		
		comp.setLayout(new FillLayout());
		final CTabFolder folder = new CTabFolder(comp, SWT.FLAT | SWT.BORDER);
		folder.setTabHeight(20);
		folder.setBorderVisible(true);
		folder.setSelectionBackground(new Color[] {new Color(null, 191, 191, 255), new Color(null, 255, 255, 255)}, new int[] {100}, true);
		folder.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				locatorIndex = folder.getSelectionIndex();
			}
		});		
		
		PortLocatorItem portItem = new PortLocatorItem(folder, SWT.NONE, pl);
		portItem.setText("Port Locator");
		portItem.createControl();
		
		ActivationLocatorItem actItem = new ActivationLocatorItem(folder, SWT.NONE, al);
		actItem.setText("Activation Locator");
		actItem.createControl();
		
		AbsoluteLocatorItem absItem = new AbsoluteLocatorItem(folder, SWT.NONE, absl);
		absItem.setText("Absolute Locator");
		absItem.createControl();
		
		CustomerLocatorItem customItem = new CustomerLocatorItem(folder, SWT.NONE, cl);
		customItem.setText("Customer Locator");
		customItem.createControl();
		
		folder.setSelection(index);
	}
	
	protected void createPreview(Composite comp) {
		GridLayout layout = new GridLayout();
		layout.numColumns = 3;
		layout.marginHeight = 10;
		layout.marginWidth = 10;
		layout.verticalSpacing = 10;
		layout.horizontalSpacing = 8;
		comp.setLayout(layout);
		
		Button preview = new Button(comp, SWT.PUSH);
		preview.setText("Preview");
		preview.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				preview();
			}
		});
		
		Button confirm = new Button(comp, SWT.PUSH);
		confirm.setText("  OK  ");
		confirm.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				returnCode = SWT.OK;
				shell.dispose();
			}
		});
		
		Button cancel = new Button(comp, SWT.PUSH);
		cancel.setText(" Cancel ");
		cancel.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				returnCode = SWT.CANCEL;
				shell.dispose();
			}
		});
	}	
	
	public AbstractLocator getOutputLocator() {
		return (AbstractLocator)locatorList.get(locatorIndex);
	}
	
	
	protected void preview() {
		origin = new Point();		
		origin.x = 50;
		origin.y = 50;
		
		preview(origin);
	}
	
	
	private void preview(Point origin) {
		contents.removeAll();
		Figure mainFigure = new DemoFigure("Parent");
		contents.add(mainFigure);
		Dimension mainDimension = new Dimension(120, 140);
		Rectangle mainBound = new Rectangle(origin, mainDimension);
		contents.setConstraint(mainFigure, mainBound);

		AbstractLocator currentLocator = (AbstractLocator)locatorList.get(locatorIndex);		
		currentLocator.setParentBound(mainBound);
		if(currentLocator instanceof PortLocatorAdapter) {
			currentLocator.setBoundNum(5);
		}
		else if(currentLocator instanceof ActivationLocatorAdapter) {
			ActivationLocatorAdapter adapter = (ActivationLocatorAdapter)currentLocator;
			adapter.clearLens();
			for(int i=0; i<5; i++) {
				adapter.addLength(10);
			}
		}
		else if(currentLocator instanceof AbsoluteLocatorAdapter) {
			Figure figure = new DemoFigure("");
			figure.setBackgroundColor(ColorConstants.yellow);
			contents.add(figure);
			
			Rectangle oldBound = new Rectangle(0, 0, 20, 20);
			Rectangle newBound = computeNewBound(origin, oldBound);
			contents.setConstraint(figure, newBound);
			return;
		}
		int boundNum = currentLocator.getBoundNum();
		for(int i=0; i < boundNum; i++) {
			Figure figure = new DemoFigure("");
			figure.setBackgroundColor(ColorConstants.yellow);
			contents.add(figure);
			
			Rectangle oldBound = new Rectangle(0, 0, 20, 20);
			oldBound = currentLocator.getNewBound(i, oldBound);
			contents.setConstraint(figure, oldBound);
		}
	}
	
	private Rectangle computeNewBound(Point origin, Rectangle oldBound) {
		Rectangle newBound = new Rectangle();
		newBound.x = origin.x + oldBound.x;
		newBound.y = origin.y + oldBound.y;
		newBound.width = oldBound.width;
		newBound.height = oldBound.height;
		return newBound;
		
	}
	/*
	protected void randomMove() {
		origin = new Point();
		Random random = new Random();		
		origin.x = random.nextInt(100);
		origin.y = random.nextInt(100);
		
		preview(origin);
	}*/
}